Skip to content

Conversation

@namest504
Copy link

@namest504 namest504 commented Oct 2, 2025

Fixes: #24744

Main Issue: #24744

PIP: 445 #24842

Motivation

The current TableView API only exposes the deserialized message value, which limits access to essential message metadata like properties, event time, or the raw message object itself.

This PR introduces a flexible, non-breaking mechanism to create value-mapped views over a topic. It replaces the initial proposal of adding a getRawMessage() method, which would have performance implications for all users. Instead, it adds a createMapped method to the TableViewBuilder, allowing users to transform a full Message<T> into any custom object V that suits their needs. This provides maximum flexibility, from accessing the full raw message to creating custom, memory-efficient objects.

Modifications

  • Added createMapped and createMappedAsync to TableViewBuilder: These new methods accept a Function<Message<T>, V> mapper, empowering users to define their own mapping from a message to a value in the TableView.
  • Refactored TableViewImpl to AbstractTableView: To avoid code duplication and support different value types, the core logic was moved to an abstract base class.
  • Introduced MessageMapperTableView: A new implementation of AbstractTableView that handles the logic for the user-defined mapper function.
  • Updated TableView: The standard TableView now extends AbstractTableView for a payload-only view, ensuring backward compatibility.

Verifying this change

  • Added new unit tests in TableViewTest.java:

    • testCreateMapped: Verifies custom mapping logic, including tombstone message handling (when the mapper returns null).
    • testCreateMappedWithIdentityMapper: Verifies that using Function.identity() correctly creates a TableView<Message<T>> with the full message object as the value.
  • All existing unit tests pass, ensuring no regressions.

  • Make sure that the change passes the CI checks.

Does this pull request potentially affect one of the following parts:

If the box was checked, please highlight the changes

  • Dependencies (add or upgrade a dependency)
  • The public API
  • The schema
  • The default values of configurations
  • The threading model
  • The binary protocol
  • The REST endpoints
  • The admin CLI options
  • The metrics
  • Anything that affects deployment

Documentation

  • doc
  • doc-required
  • doc-not-needed
  • doc-complete

Matching PR in forked repository

PR in forked repository: fork-repo

@github-actions github-actions bot added the doc-required Your PR changes impact docs and you will update later. label Oct 2, 2025
…agement by adding retain() before storing message to rawMessages

- Prevent premature message release that causes getRawMessage to return null keys.
- Ensure message reference count is balanced by retaining message before storing and releasing old message after replacement.
- Keep message release in finally block for safety.
Copy link
Member

@lhotari lhotari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution!

Since this changes the Pulsar API, we'd need to first go through the PIP process to modify the public API.

Instead of adding a separate ConcurrentMap for storing the messages, I'd suggest going with an approach where the TableViewBuilder would have separate methods for creating a view for messages.

TableView<Message<T>> createForMessages() throws PulsarClientException;
CompletableFuture<TableView<Message<T>>> createForMessagesAsync() throws PulsarClientException;

I'm not exactly sure if there's any obstacles with this approach, but it seems that it could be a better way forward so that the existing runtime behavior of TableView implementation wouldn't change (like it does with the current PR changes).

@namest504
Copy link
Author

Hi @lhotari,

Thanks for the review and the great suggestion about using the TableViewBuilder!

I completely agree that we should avoid impacting the runtime behavior for existing users.

As you recommended, I've created a PIP for this API change, which you can find here: #24842

Let's continue the design discussion over on the PIP PR.

@lhotari
Copy link
Member

lhotari commented Oct 14, 2025

Hi @lhotari,

Thanks for the review and the great suggestion about using the TableViewBuilder!

I completely agree that we should avoid impacting the runtime behavior for existing users.

As you recommended, I've created a PIP for this API change, which you can find here: #24842

Let's continue the design discussion over on the PIP PR.

@namest504 you seemed to ignore the suggestion in the comment. I'd suggest revisiting the PIP accordingly and renaming it. You can reply to the comment on the PIP PR, #24842 (review).

@namest504 namest504 changed the title [improve][api] Add getRawMessage() method to TableView for accessing raw Pulsar message [improve][api] Add Builder Methods to Create Message-based TableView Oct 20, 2025
@namest504 namest504 requested a review from lhotari October 20, 2025 04:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

doc-required Your PR changes impact docs and you will update later.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API to allow access to raw message for TableView

2 participants